package com.boardour.toupin.show;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.boardour.base.ui.AppActivity;
import com.boardour.base.ui.titlebar.DefTitleBar;
import com.boardour.socket.listener.OnReceiveListener;
import com.boardour.socket.server.WifiServerPresenter;
import com.boardour.toupin.R;
import com.boardour.toupin.VideoUtils;
import com.boardour.wifip2p.WifiP2pCommon;
import com.boardour.wifip2p.packet.BytesReceivePacket;
import com.boardour.wifip2p.popup.WifiP2pListPopup;
import com.boardour.wifip2p.receiver.ConnectListenerAdapter;
import com.boardour.wifip2p.receiver.ConnectManager;

import java.net.InetAddress;
import java.nio.channels.SocketChannel;

import cn.carhouse.permission.Permission;
import cn.carhouse.permission.XPermission;
import cn.carhouse.permission.callback.PermissionListenerAdapter;

/**
 * 投屏接收端
 */
public class ShowActivity extends AppActivity implements OnReceiveListener {
    private TextView btn;
    private TextureView surfaceView;
    private ShowDecode decode;
    int FLAGS_FULLSCREEN =
            View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;

    private ConnectManager connectManager;


    @Override
    public void onReceive(int trackIndex, byte[] data, long presentationTimeUs, SocketChannel channel) {
        if (decode == null) {
            return;
        }
        BytesReceivePacket packet = new BytesReceivePacket((byte) trackIndex, data, presentationTimeUs);
        decode.offer(packet);
    }

    @Override
    protected void initTitle(DefTitleBar titleBar) {
        titleBar.setTitle("安博斯投屏接收端");
    }

    @Override
    public int getContentLayout() {
        return R.layout.activity_show;
    }

    @Override
    public void initData(Bundle savedInstanceState) {
        startService();
    }

    @Override
    public void initViews(View view) {
        btn = findViewById(R.id.btn);
        surfaceView = findViewById(R.id.surface_view);
        surfaceView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                surface.setDefaultBufferSize(VideoUtils.DECODE_WIDTH, VideoUtils.DECODE_HEIGHT);
                setUpDecode(new Surface(surface));
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }
        });

        if (hasPermissions(this, permissions)) {
            initListener();
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(permissions, 100);
            }
        }

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPop();
            }
        });
    }

    public void showPop() {
        XPermission.with(this)
                .permissions(Permission.LOCATION)
                .request(new PermissionListenerAdapter() {
                    @Override
                    public void onSucceed() {
                        realShowPop();
                    }
                });
    }

    private void realShowPop() {
        WifiP2pListPopup popup = new WifiP2pListPopup(this, true);
        popup.show();
    }

    private String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};

    private boolean hasPermissions(Context context, String... permissions) {
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 100) {
            if (grantResults != null && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
                initListener();
            }
        }
    }

    private void initListener() {
        connectManager = new ConnectManager();
        // WifiP2p状态监听
        connectManager.setConnectListener(new ConnectListenerAdapter() {

            @Override
            public void onWifiP2pStateChanged(boolean wifiP2pEnable) {
                if (!wifiP2pEnable) {
                    WifiP2pCommon.getInstance().startWifiSetting();
                } else {
                    requestMineInfo();
                }
            }

            @Override
            public void onWifiP2pDeviceChanged(WifiP2pDevice wifiP2pDevice) {
                showDevice(wifiP2pDevice);
            }
        });
    }

    private void requestMineInfo() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                WifiP2pCommon.getInstance().requestDeviceInfo(new WifiP2pManager.DeviceInfoListener() {
                    @Override
                    public void onDeviceInfoAvailable(@Nullable WifiP2pDevice wifiP2pDevice) {
                        showDevice(wifiP2pDevice);
                    }
                });
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }

    }

    private WifiP2pDevice device;

    private void showDevice(WifiP2pDevice wifiP2pDevice) {
        this.device = wifiP2pDevice;
        if (wifiP2pDevice == null) {
            return;
        }
        changePeers();
        WifiP2pCommon.getInstance().requestConnectionInfo(new WifiP2pManager.ConnectionInfoListener() {
            @Override
            public void onConnectionInfoAvailable(WifiP2pInfo info) {
                if (WifiP2pDevice.AVAILABLE != wifiP2pDevice.status) {
                    WifiP2pCommon.getInstance().stopPeerDiscovery();
                } else {
                    WifiP2pCommon.getInstance().discoverPeers();
                }
                InetAddress address = info.groupOwnerAddress;
                StringBuffer sb = new StringBuffer();
                sb.append("" + wifiP2pDevice.deviceName)
                        .append("\r\n")
                        .append(""
                                + WifiP2pCommon.getDeviceStatus(wifiP2pDevice.status))
                        .append(":" + info.isGroupOwner);
                if (address != null) {
                    sb.append("\r\n").append(address.toString());
                }
                if (decode != null) {
                    decode.reset(WifiP2pDevice.CONNECTED == wifiP2pDevice.status);
                }
                sb.append("\r\nWifi列表");
                btn.setText(sb.toString());

                doConnect(wifiP2pDevice);
            }
        });

    }

    private void changePeers() {
        if (device == null) {
            return;
        }
        if (device.status == WifiP2pDevice.CONNECTED) {
            WifiP2pCommon.getInstance().stopPeerDiscovery();
        } else if (device.status == WifiP2pDevice.AVAILABLE) {
            WifiP2pCommon.getInstance().discoverPeers();
        }
    }

    private void doConnect(WifiP2pDevice wifiP2pDevice) {
        if (wifiP2pDevice.status == WifiP2pDevice.CONNECTED) {
            WifiP2pCommon.getInstance().requestConnectionInfo(new WifiP2pManager.ConnectionInfoListener() {
                @Override
                public void onConnectionInfoAvailable(WifiP2pInfo info) {
                    InetAddress address = info.groupOwnerAddress;
                    if (address != null) {
                        // 要给对方发个地址
                        if (!info.isGroupOwner) {
                            // 地址是对方的，要连接一下对方
                            WifiServerPresenter.getInstance().connectClient(address);
                        }
                    } else {
                        doConnect(wifiP2pDevice);
                    }
                }
            });
        }

    }

    private void setUpDecode(Surface surface) {
        decode = new ShowDecode();
        decode.start(surface);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (connectManager != null) {
            // 注册状态监听
            connectManager.registerBroadcastReceiver(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (connectManager != null) {
            // 反注册状态监听
            connectManager.unregisterBroadcastReceiver(this);
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopService();
        WifiP2pCommon.getInstance().removeGroup();
    }


    /**
     * 开启接收客户端的数据
     */
    private void startService() {
        WifiServerPresenter.getInstance().setOnReceiveListener(this);
        WifiServerPresenter.getInstance().start();
    }

    /**
     * 停止接收客户端的数据
     */
    private void stopService() {
        WifiServerPresenter.getInstance().close();
        if (decode != null) {
            decode.close();
        }
    }


}
